package com.wmh.baseservice.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wmh.baseservice.admin.pojo.AdRolePermissions;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.redis.config.RedisConfig;
import com.wmh.baseservice.common.redis.utils.RedisUtil;
import com.wmh.baseservice.common.shiro.config.ShiroConfig;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.LogUtil;
import com.wmh.baseservice.user.pojo.UsRolePermissions;
import com.wmh.baseservice.user.mapper.UsRolePermissionsMapper;
import com.wmh.baseservice.user.service.UsRolePermissionsService;
import com.wmh.baseservice.common.mybatisplus.methods.CommonServiceImpl;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author mmx generator
 * @since 2021-11-02
 */
@Service
public class UsRolePermissionsServiceImpl extends CommonServiceImpl<UsRolePermissionsMapper, UsRolePermissions> implements UsRolePermissionsService {


    @Resource
    private UsRolePermissionsService usRolePermissionsService;
    @Resource
    private RedisUtil redisUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInfo(UsRolePermissions usRolePermissions, String s) {
        if (!usRolePermissionsService.updateById(usRolePermissions)) {
            throw new ServiceException();
        }
        //更新所有用户角色权限
        List<UsRolePermissions> usRolePermissionsList = usRolePermissionsService.listForUpdate(usRolePermissions.getType() == 1 ? new QueryWrapper<UsRolePermissions>().eq(AdRolePermissions.ROLE, s)
                : new QueryWrapper<UsRolePermissions>().eq(UsRolePermissions.PERMISSIONS, s));
        usRolePermissionsList.forEach(item -> {
            if (usRolePermissions.getType() == 1) {
                item.setRole(usRolePermissions.getRole());
            } else {
                item.setPermissions(usRolePermissions.getPermissions());
            }
        });
        if (usRolePermissionsList.size() != 0) {
            if (!usRolePermissionsService.updateBatchById(usRolePermissionsList)) {
                throw new ServiceException();
            }
        }
        usRolePermissionsList.forEach(item -> {
            String project = RedisConfig.KEY_INFO;
            String key = "role_permissions_" + item.getUsId() + ShiroConfig.SHIRO_USER + project;
            try {
                //更新redis队列
                SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) redisUtil.get(key);
                if (CommUtil.checkNull(info)) {
                    Set<String> set = new HashSet<>();
                    SimpleAuthorizationInfo newInfo = new SimpleAuthorizationInfo();
                    if (usRolePermissions.getType() == 1) {
                        newInfo.setStringPermissions(info.getStringPermissions());
                        set.add(item.getRole());
                        newInfo.setRoles(set);
                    } else {
                        newInfo.setRoles(info.getRoles());
                        newInfo.setStringPermissions(usRolePermissionsList.size() == 0 ? new HashSet<>() : usRolePermissionsList
                                .stream().map(UsRolePermissions::getPermissions).collect(Collectors.toSet()));
                    }
                    redisUtil.set(key, newInfo);
                }
            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.error("redis角色权限添加错误,key是:" + key + "。原因是:" + e.getMessage());
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setPer(Long id, List<UsRolePermissions> usRolePermissions) {
        //删除该账号原权限
        List<Long> list = usRolePermissionsService.list(new QueryWrapper<UsRolePermissions>().eq(UsRolePermissions.US_ID, id).eq(UsRolePermissions.TYPE, 2)).stream().map(UsRolePermissions::getId).collect(Collectors.toList());
        if (list.size() != 0) {
            if (!usRolePermissionsService.removeByIds(list)) {
                throw new ServiceException();
            }
        }
        if (usRolePermissions.size() != 0) {
            //添加该账号权限
            if (!usRolePermissionsService.saveBatch(usRolePermissions)) {
                throw new ServiceException();
            }
        }
        //更新redis
        String project = RedisConfig.KEY_INFO;
        String key = "role_permissions_" + id + ShiroConfig.SHIRO_USER + project;
        try {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            SimpleAuthorizationInfo infoRaw = (SimpleAuthorizationInfo) redisUtil.get(key);
            info.setRoles(CommUtil.checkNull(infoRaw) ? infoRaw.getRoles() : null);
            Set<String> permissions = usRolePermissions.size() == 0 ? new HashSet<>() : usRolePermissions.stream().filter(item -> CommUtil.checkNull(item.getPermissions())).map(UsRolePermissions::getPermissions).collect(Collectors.toSet());
            info.setStringPermissions(permissions);
            redisUtil.set(key, info);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error("redis角色权限更新错误,key是:" + key + "。原因是:" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, Integer type) {
        //删除角色权限
        UsRolePermissions usRolePermissions = usRolePermissionsService.getByIdForUpdate(id);
        if (!CommUtil.checkNull(usRolePermissions)) {
            throw new ServiceException();
        }
        List<UsRolePermissions> usRolePermissionsList = usRolePermissionsService.listForUpdate(type == 1 ? new QueryWrapper<UsRolePermissions>()
                .eq(UsRolePermissions.ROLE, usRolePermissions.getRole()) : new QueryWrapper<UsRolePermissions>()
                .eq(UsRolePermissions.PERMISSIONS, usRolePermissions.getPermissions()));
        List<Long> idList;
        idList = usRolePermissionsList.stream().map(UsRolePermissions::getId).collect(Collectors.toList());
        if (idList.size() != 0) {
            if (!usRolePermissionsService.removeByIds(idList)) {
                throw new ServiceException();
            }
        }
        idList = usRolePermissionsList.stream().filter(item -> CommUtil.checkNull(item.getUsId())).map(UsRolePermissions::getUsId).collect(Collectors.toList());
        if (type == 1) {
            //删除角色权限redis
            idList.forEach(item -> {
                String project = RedisConfig.KEY_INFO;
                String key = "role_permissions_" + item + ShiroConfig.SHIRO_USER + project;
                redisUtil.del(key);
            });
        }else {
            //更新接口权限
            idList.forEach(item -> {
                String project = RedisConfig.KEY_INFO;
                String key = "role_permissions_" + item + ShiroConfig.SHIRO_USER + project;
                SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) redisUtil.get(key);
                if (CommUtil.checkNull(info)){
                    SimpleAuthorizationInfo newInfo = new SimpleAuthorizationInfo();
                    newInfo.setRoles(info.getRoles());
                    info.getStringPermissions().remove(usRolePermissions.getPermissions());
                    newInfo.setStringPermissions(info.getStringPermissions());
                    redisUtil.set(key,newInfo);
                }
            });
        }
    }
}

